package core;

import CommitLink.CommitLink;
import CommitLink.LinkList;
import Index.Index;
import Index.TreeNode;
import fileoperation.FileDeletion;
import gitobject.Blob;
import gitobject.Commit;
import gitobject.GitObject;
import repository.Repository;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class JitReset {
    public  static  String reset_soft(String ID) throws IOException {
        File HEAD = new File(new File(".").getCanonicalPath() + File.separator+ ".jit" + File.separator + "HEAD");
        if (GitObject.getValue(HEAD).length() == 0){
            System.out.println("目前还没有任何提交");
        }
        String path = GitObject.getValue(HEAD).substring(5).replace("\n", "");
        File headID = new File(new File(".").getCanonicalPath() + File.separator+ ".jit" + File.separator + path);
        PrintWriter output = new PrintWriter(headID);
        String newID = findHead(ID);
//        System.out.println(newID + "########");
//        System.out.println(ID);
        output.print(newID);
        output.close();
        return newID;
    }

    //实现暂存区替代
    public  static  void reset_mid(String ID) throws Exception {
        //先更改目前head指向,即reset_soft
        String commitID=reset_soft(ID);
        //String pathOfCommit=findCommit(ID);
        //根据Id来搜寻commit tree
        //System.out.println(pathOfCommit);
        CommitLink commitLink = new CommitLink();
        LinkList list = commitLink.getCommitList();
        //获取对应的commit
        Commit commit=list.findByValue(commitID).getCommit();
        //获取此次commit的treenode
        TreeNode commitTree=commit.indexTree;
        //将treenode写入到index区，实现覆盖
        Index index = new Index();
        index.setIndexTree(commitTree);

        index.writeObject();

    }
    public static void  reset_hard(String ID) throws Exception {
        //清空当前工作区
        String tempId = ID;
        if(ID.startsWith("###")) {
            tempId = ID.substring(3);
            JitBranch.clear_work();
        }else{
            clear_work();
        }
        reset_mid(tempId);
        Index index = new Index();
        TreeNode resetHard_TreeNode= index.getIndexTree();
        //对当前暂存区进行遍历，创建文件,依然使用层次遍历
        Queue<TreeNode> q=new LinkedList<>();
        q.add(resetHard_TreeNode);
        while(!q.isEmpty()){
            TreeNode current=q.poll();

            if(current.getType()!=null) {
                rebuiltTree(current);
            }
            if(current.getChildren()!=null){
                ArrayList<TreeNode> children = current.getChildren();
                Iterator<TreeNode> iterator=children.iterator();
                while(iterator.hasNext()){
                    q.add(iterator.next());
                }
            }

        }

    }
    //重建工作区的函数,根据某个tree
    public static void rebuiltTree(TreeNode workTree) throws IOException {
        //对树和文件分别处理
        if(workTree.getType().equals("tree")&& !Objects.equals(workTree.getpath(), Repository.getWorkTree())){
            String path= workTree.getpath();
            File tree=new File(path);
            if(!tree.exists()){
                tree.mkdir();
            }
        }
        if(workTree.getType().equals("blob")){
            String path= workTree.getpath();
            String hashId=workTree.getId();
            //根据hash到object中寻找这个blob
            String blobOfBlob=new File(".").getCanonicalPath() + File.separator+ ".jit"+File.separator + "objects" + File.separator + hashId.substring(0,2)+File.separator+hashId.substring(2,hashId.length());

            File blob = new File(path);

            //覆盖文件
            blob.createNewFile();
            Copy.copy(blobOfBlob,path);
        }

    }
    //清空工作区
    public static void clear_work() throws Exception {
        String workTreePath = Repository.getWorkTree();
        File workTree = new File(workTreePath);
        //获得过滤后的文件列表
        File[] list=workTree.listFiles(new MyFilter());
        //逐一删除文件
        for (File del:list
        ) {
            FileDeletion.deleteFile(del);
        }
        System.out.println("工作区已经清空");

    }
    //创建一个过滤器，将工作区下.jit文件不包括在内
    static class MyFilter implements FileFilter {
        public boolean accept(File file) {

            try {
                return !file.getAbsolutePath().startsWith(new File(".").getCanonicalPath() + File.separator+ ".jit");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }
    }


    static class Copy{
        public static void copy(String blobPath,String workPath) throws IOException{
            Blob blob = Blob.deserialize(blobPath);

            File targetFile=new File(workPath);
            try(
//                    BufferedInputStream input= new BufferedInputStream(new FileInputStream(sourceFile));

                    BufferedOutputStream output=new BufferedOutputStream(new FileOutputStream(targetFile));
                    ){
//                int r=0;
//                while((r=input.read())!=-1){
                    output.write(blob.getValue().getBytes(StandardCharsets.UTF_8));
//                }
            }

        }
    }
    //根据前缀寻找ID
    public static String findHead(String prefixes) throws IOException {
        String dicPart=prefixes.substring(0,2);
        String filePart=prefixes.substring(2,prefixes.length());
        File dic=new File(new File(".").getCanonicalPath() + File.separator+ ".jit"+File.separator+"objects"+File.separator+dicPart);
        File[] fs=dic.listFiles();
        if(fs == null){
            return null;
        }
        for (File cur:fs) {
            //System.out.println(cur.getAbsolutePath());
            if(cur.getAbsolutePath().contains(filePart)){
                int index=cur.getAbsolutePath().lastIndexOf(dicPart);
                String temp= cur.getAbsolutePath().substring(index);
                return temp.substring(0,2)+temp.substring(3);
            }
        }
        System.out.println("没有找到对应指针");
        return null;
    }
    //
    public static String findCommit(String prefixes) throws IOException {
        String dicPart=prefixes.substring(0,2);
        String filePart=prefixes.substring(2,prefixes.length());
        File dic=new File(new File(".").getCanonicalPath() + File.separator+ ".jit"+File.separator+"objects"+File.separator+dicPart);
        File[] fs=dic.listFiles();
        for (File cur:fs) {
            if(cur.getAbsolutePath().contains(filePart)){
                return cur.getAbsolutePath();
            }
        }
        System.out.println("没有找到对应指针");
        return null;
    }
}


